<script lang="ts" setup>
import type { Rule } from 'ant-design-vue/es/form';

import type { UnwrapRef } from 'vue';

import type { TagGroupVO } from '#/api/company/tag/model';

import { computed, h, onMounted, reactive, ref } from 'vue';

import { useVbenModal } from '@vben/common-ui';
import { DictEnum } from '@vben/constants';
// import { useBeforeCloseDiff } from '#/utils/popup';
import { VbenIcon } from '@vben/icons';

import { ClearOutlined, DeleteOutlined } from '@ant-design/icons-vue';
import {
  Button,
  Checkbox,
  Divider,
  Empty,
  Form,
  FormItem,
  InputSearch,
  Popconfirm,
  RadioGroup,
  Segmented,
  TabPane,
  Tabs,
} from 'ant-design-vue';

import { tagGroupList } from '#/api/company/tag';
import { personalTagGroupList } from '#/api/company/tag/personal';
import { dictDataInfo } from '#/api/system/dict/dict-data';
import { ColorTag } from '#/components/dict';
import { getDictOptions } from '#/utils/dict';

const props = withDefaults(defineProps<Props>(), {
  tagType: undefined, // 1企业标签 2人员标签
  showOp: true, // 是否开启条件选择
  confirmedClose: true, // 点击确认按钮后是否关闭弹窗，父组件需控制关闭时可传false
});

const emit = defineEmits(['confirm']);

interface Props {
  tagType?: number | string;
  showOp?: boolean;
  confirmedClose?: boolean;
}

const typeOptions = [
  { value: 1, payload: { icon: 'bxs:building-house', label: '公司级别' } },
  { value: 2, payload: { icon: 'fa6-solid:user-tag', label: '个人级别' } },
];
const currentType = ref(1);
const categoryDicts = ref<Record<string, any>[]>([]);
const tagGroupSearch = ref<string>();
const currCategory = ref<number | string>();
const currTagGroups = ref<TagGroupVO[]>([]);

const tagSearch = ref<string>();

const selectedTagIdList = ref<(number | string)[]>([]);
// const confirmedTagList = ref<(number | string)[]>([]);
const tagTypeTitle = computed(() => {
  return props.tagType === 1 ? '企业标签' : '人员标签';
});

interface ModalData {
  ids: (number | string)[];
  confirmedOptions: any[];
  op?: number | string;
}

const [BasicModal, modalApi] = useVbenModal({
  title: `选择${tagTypeTitle.value}`,
  fullscreenButton: false,
  onClosed: handleClosed,
  onConfirm: handleConfirm,
  onOpenChange: async (isOpen) => {
    if (!isOpen) {
      return null;
    }
    modalApi.modalLoading(true);

    const { ids, confirmedOptions, op } = modalApi.getData() as ModalData;
    // console.log('modalApi.getData()', modalApi.getData());
    if (ids?.length > 0) {
      // 恢复初始值
      selectedTagIdList.value = ids;
      selectedOptions.value = confirmedOptions;
      filterForm.op = op as string;
    } else {
      clearAll();
    }
    await getCategoryList();
    await getTagGroupList();
    modalApi.modalLoading(false);
  },
});

// 筛选后确认
async function handleConfirm() {
  try {
    if (props.showOp) {
      await filterFormRef.value.validate();
    }

    if (props.confirmedClose) {
      modalApi.modalLoading(true);
    }
    console.log('当前所选标签：', selectedTagIdList.value);
    confirmedOptions.value = selectedOptions.value;
    emit('confirm', {
      ids: selectedTagIdList.value,
      options: confirmedOptions.value,
      op: filterForm.op,
    });
    if (props.confirmedClose) {
      modalApi.close();
    }
  } catch (error) {
    console.error(error);
  } finally {
    if (props.confirmedClose) {
      modalApi.lock(false);
    }
  }
}

async function handleClosed() {
  // resetInitialized();
}

// 查询标签组类别
const categoryDictEnum = computed(() => {
  if (props.tagType === 1) {
    return currentType.value === 1
      ? DictEnum.COMPANY_TAG_COMPANY_CATEGORY
      : DictEnum.COMPANY_TAG_PERSONAL_CATEGORY;
  }

  return currentType.value === 1
    ? DictEnum.PERSONAL_TAG_COMPANY_CATEGORY
    : DictEnum.PERSONAL_TAG_PERSONAL_CATEGORY;
});

async function getCategoryList() {
  categoryDicts.value = await dictDataInfo(categoryDictEnum.value);
  if (categoryDicts.value.length > 0) {
    currCategory.value = (categoryDicts.value as Array<any>)[0].dictValue;
  }
}

// 查询标签组
async function getTagGroupList() {
  modalApi.modalLoading(true);
  const queryData = {
    type: currentType.value,
    category: currCategory.value,
    name: tagGroupSearch.value,
    labelName: tagSearch.value,
  };
  const list: TagGroupVO[] =
    props.tagType === 1
      ? await tagGroupList(queryData)
      : await personalTagGroupList(queryData);

  currTagGroups.value =
    list.map((group) => {
      if (group.labels) {
        group.labels = group.labels.map((tag) => {
          tag.groupName = group.name;
          return tag;
        });
      }
      return group;
    }) || [];
  modalApi.modalLoading(false);
  return list;
}

// 标签级别切换
async function handleTypeChange(type: number) {
  modalApi.modalLoading(true);
  currentType.value = type;
  await getCategoryList();
  await getTagGroupList();
  modalApi.modalLoading(false);
}

const selectedOptions = ref<any[]>([]);
const confirmedOptions = ref<any[]>([]);

// 确认按钮文本
const confirmText = computed(() => {
  return `确认(${selectedTagIdList.value.length})`;
});

// 重组已选的标签（分组）
const selectedGroupList = computed(() => {
  if (selectedTagIdList.value.length === 0) return [];

  const map = new Map<string, Record<string, any>>();

  for (const item of selectedOptions.value) {
    if (!map.has(item.groupName)) {
      map.set(item.groupName, { groupName: item.groupName, labels: [] });
    }
    map.get(item.groupName)!.labels.push({ ...item });
  }

  return [...map.values()];
  // return selectedTagIdList.value;
});

// 标签选择监听
function handleTagCheckChange(e: any, group: any) {
  console.log(e.target, group);
  const value = e.target.value;
  selectedOptions.value = selectedOptions.value.some(
    (item) => item.value === value.id,
  )
    ? selectedOptions.value.filter((item) => item.value !== value.id)
    : [
        ...selectedOptions.value,
        {
          label: value.name,
          value: value.id,
          groupName: value.groupName,
          status: value.status,
          listClass: value.listClass,
        },
      ];

  selectedTagIdList.value = selectedTagIdList.value.includes(value.id)
    ? selectedTagIdList.value.filter((id) => id !== value.id)
    : [...selectedTagIdList.value, value.id];

  // emit('update:checkedValues', ids);
}

// 判断当前分组是否“全选”
function isCheckAll(group: any) {
  const labelIds = group.labels.map((l: any) => l.id);
  return (
    labelIds.length > 0 &&
    labelIds.every((id: any) => selectedTagIdList.value.includes(id))
  );
}

// 判断当前分组是否“半选”
function isIndeterminate(group: any) {
  const labelIds = group.labels.map((l: any) => l.id);
  const selectedCount = labelIds.filter((id: any) =>
    selectedTagIdList.value.includes(id),
  ).length;
  return selectedCount > 0 && selectedCount < labelIds.length;
}

// 点击“全选”按钮时
function onCheckAllChange(e: any, group: any) {
  console.log(e, group);
  const labelIds = group.labels.map((l: any) => l.id);

  selectedOptions.value = e.target.checked
    ? [
        ...new Map(
          [
            ...selectedOptions.value,
            ...group.labels.map((label: any) => ({
              label: label.name,
              value: label.id,
              groupName: label.groupName,
              status: label.status,
              listClass: label.listClass,
            })),
          ].map((i) => [i.value, i]),
        ).values(),
      ]
    : selectedOptions.value.filter(
        (item) => !group.labels.some((v: any) => v.id === item.value),
      );

  selectedTagIdList.value = e.target.checked
    ? [...new Set([...labelIds, ...selectedTagIdList.value])]
    : selectedTagIdList.value.filter((id) => !labelIds.includes(id));
}

// 清空所有数据，恢复到初始状态
function clearAll() {
  if (props.showOp) {
    filterFormRef.value?.resetFields();
  }
  selectedTagIdList.value = [];
  selectedOptions.value = [];
  confirmedOptions.value = [];
  currentType.value = 1;
  filterForm.op = '';
  if (categoryDicts.value.length > 0) {
    currCategory.value = (categoryDicts.value as Array<any>)[0].dictValue;
  }
}

// 清空已选的所有标签
function handleClearAllSelected() {
  selectedTagIdList.value = [];
  selectedOptions.value = [];
}

// 清空已选的分组所有标签
function handleClearGroupSelected(labels: any) {
  console.log(labels);
  selectedOptions.value = selectedOptions.value.filter(
    (item) => !labels.some((v: any) => v.value === item.value),
  );
  selectedTagIdList.value = selectedTagIdList.value.filter(
    (id) => !labels.some((v: any) => v.value === id),
  );
}

// 清空单个已选标签
function handleClearSelectedItem(tag: any) {
  if (selectedOptions.value.some((item) => item.value === tag.value)) {
    selectedOptions.value = selectedOptions.value.filter(
      (item) => item.value !== tag.value,
    );
  }
  if (selectedTagIdList.value.includes(tag.value)) {
    selectedTagIdList.value = selectedTagIdList.value.filter(
      (id) => id !== tag.value,
    );
  }
}

// function resetForm() {
//   console.log('resetForm');
// }

interface FilterForm {
  op: string;
}

const filterFormRef = ref();
const filterForm: UnwrapRef<FilterForm> = reactive({
  op: '',
});
const filterFormRules: Record<string, Rule[]> = {
  op: [{ required: true, message: '请选择查询条件', trigger: 'change' }],
};

onMounted(async () => {
  // console.log(categoryDicts.value.length);
  // console.log('onMOunted');
});

defineExpose({
  clearAll,
});
</script>
<template>
  <BasicModal
    class="w-[1200px]"
    :confirm-disabled="selectedTagIdList.length === 0"
    :confirm-text="confirmText"
  >
    <div class="flex h-full gap-[20px] overflow-hidden" style="height: 480px">
      <div class="bg-card h-full flex-1 rounded-md">
        <div class="z-100 sticky left-0 top-0 m-auto mb-4 w-[300px]">
          <Segmented
            v-model:value="currentType"
            :options="typeOptions"
            block
            class="mb-2 text-center"
            @change="handleTypeChange(currentType)"
          >
            <template #label="{ payload = {} }">
              <div class="flex items-center gap-1">
                <VbenIcon :icon="payload.icon" />
                <span>{{ payload.label }}</span>
              </div>
            </template>
          </Segmented>
        </div>
        <div class="h-full pb-[50px]">
          <div class="thin-scrollbar h-full overflow-hidden overflow-y-auto">
            <Tabs
              v-model:active-key="currCategory"
              size="small"
              tab-position="left"
              type="line"
              :tab-bar-style="{ maxWidth: '320px' }"
              style="height: 100%"
              @change="getTagGroupList"
            >
              <template #leftExtra>
                <div class="pb-[12px] text-[#C0C4CC]">标签组类别</div>
              </template>
              <TabPane v-for="c in categoryDicts" :key="c.dictValue">
                <template #tab>
                  <VbenIcon
                    icon="material-symbols:category-outline-rounded"
                    class="mr-[5px] inline-block"
                  />
                  {{ c.dictLabel }}
                </template>
                <div class="h-full">
                  <div class="flex justify-start gap-5">
                    <InputSearch
                      v-model:value="tagGroupSearch"
                      placeholder="搜索标签组"
                      size="middle"
                      @search="getTagGroupList"
                    />
                    <InputSearch
                      v-model:value="tagSearch"
                      placeholder="搜索标签"
                      size="middle"
                      @search="getTagGroupList"
                    />
                  </div>
                  <div
                    class="thin-scrollbar flex h-full overflow-hidden overflow-y-auto pt-[30px]"
                    style="height: 390px"
                  >
                    <div v-if="currTagGroups.length > 0" class="w-full">
                      <div
                        v-for="group in currTagGroups"
                        :key="group.id"
                        class="mb-[30px]"
                      >
                        <!--<div class="pb-[12px] text-[#C0C4CC]">-->
                        <!--  {{ group.name }} ({{ group.labels.length }})-->
                        <!--</div>-->
                        <Divider>
                          <Checkbox
                            :indeterminate="isIndeterminate(group)"
                            :checked="isCheckAll(group)"
                            @change="onCheckAllChange($event, group)"
                          />
                          {{ group.name }} ({{ group.labels.length }})
                        </Divider>
                        <div v-if="group.labels?.length > 0">
                          <!--<CheckableTag-->
                          <!--  v-for="tag in group.labels"-->
                          <!--  :key="tag.id"-->
                          <!--  v-model:value="selectedTagIdList"-->
                          <!--  class="px-[10px] py-[6px] text-[14px]"-->
                          <!--  @change="handleTagCheckChange"-->
                          <!--&gt;-->
                          <!--  {{ tag.name }}-->
                          <!--</CheckableTag>-->
                          <Checkbox
                            v-for="tag in group.labels"
                            :key="tag.id"
                            :checked="selectedTagIdList.includes(tag.id)"
                            :disabled="tag.status === '1'"
                            :value="tag"
                            class="px-[10px] py-[6px] text-[14px]"
                            @change="handleTagCheckChange($event, group)"
                          >
                            {{ tag.name }}
                          </Checkbox>
                        </div>
                      </div>
                    </div>
                    <Empty v-else description="暂无标签" class="w-full" />
                  </div>
                </div>
              </TabPane>
            </Tabs>
          </div>
        </div>
      </div>
      <div
        class="bg-background-deep thin-scrollbar h-full w-[370px] overflow-hidden overflow-y-auto p-[20px]"
      >
        <div class="font-bold">
          <span>已选标签（共{{ selectedTagIdList.length }}个）</span>
          <Popconfirm
            v-if="selectedGroupList.length > 0"
            title="确认清除已选的所有标签吗？"
            placement="bottom"
            @confirm="handleClearAllSelected"
          >
            <Button type="link" :icon="h(ClearOutlined)" danger>
              清除所有已选标签
            </Button>
          </Popconfirm>
          <div v-for="(item, i) in selectedGroupList" :key="i">
            <div class="my-[12px] text-[14px] text-[#909399]">
              <span>{{ item.groupName }}（{{ item.labels.length }}）</span>
              <Popconfirm
                title="确认清除该分组所选的标签吗？"
                placement="top"
                @confirm="handleClearGroupSelected(item.labels)"
              >
                <Button
                  type="link"
                  :icon="h(DeleteOutlined)"
                  danger
                  title="清除该组所选标签"
                />
              </Popconfirm>
            </div>
            <div v-if="item.labels?.length > 0">
              <!--<Tag-->
              <!--  v-for="tag in item.labels"-->
              <!--  :key="tag.id"-->
              <!--  class="mb-[5px] mr-[5px]"-->
              <!--  :bordered="true"-->
              <!--  color="processing"-->
              <!--  closable-->
              <!--  @close.prevent="handleClearSelectedItem(tag)"-->
              <!--&gt;-->
              <!--  {{ tag.name }}-->
              <!--</Tag>-->
              <ColorTag
                v-for="tag in item.labels"
                :key="tag.value"
                :color="tag.listClass"
                :label="tag.label"
                class="mb-[5px] mr-[5px]"
                :disabled="tag.status === '1'"
                closable
                @close="handleClearSelectedItem(tag)"
              />
            </div>
          </div>
          <Empty
            v-if="selectedGroupList.length === 0"
            description="您还没有选择标签"
            class="mt-[80px] w-full"
          />
        </div>
      </div>
    </div>
    <template #prepend-footer>
      <slot name="prepend-footer"></slot>
      <div v-if="showOp" class="flex items-center">
        <Form ref="filterFormRef" :model="filterForm" :rules="filterFormRules">
          <FormItem label="筛选条件" class="mb-0" name="op">
            <RadioGroup
              v-model:value="filterForm.op"
              :options="getDictOptions(DictEnum.TAG_FILTER_CONDITION)"
            />
          </FormItem>
        </Form>
      </div>
    </template>
  </BasicModal>
</template>
